using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;

using SlimDX.Direct3D9;

using miciv.Rendering;

namespace miciv
{
    public class BitmapFont
    {
        protected CoreContext m_coreContext;
        protected BitmapFontInfo m_bmfInfo;
        protected BitmapFontCommon m_bmfCommon;
        protected Hashtable m_htblPages;
        protected Hashtable m_htblChars;
        protected Hashtable m_htblKernings;
        protected string m_strLocationPath;

        public BitmapFont()
        {
            this.m_bmfInfo = new BitmapFontInfo();
            this.m_bmfCommon = new BitmapFontCommon();
            this.m_htblPages = new Hashtable();
            this.m_htblChars = new Hashtable();
            this.m_htblKernings = new Hashtable();
        }

        public bool Initialize(CoreContext _coreContext, string _strLocation)
        {
            //XmlDocument xmlDoc = _coreContext.m_coreManager.LoadXml(_strLocation, false);
            XmlDocument xmlDoc = _coreContext.CoreManager.LoadXml(_strLocation, false);
            XmlTraverser xmlTraverser = new XmlTraverser(xmlDoc.DocumentElement);
            XmlListenerBMF fontCreator = new XmlListenerBMF();

            this.m_coreContext = _coreContext;
            this.m_strLocationPath = System.IO.Path.GetDirectoryName(_strLocation);
            fontCreator.Initialize(this, _coreContext, xmlTraverser);
            fontCreator.Attach();
            xmlTraverser.Traverse();
            fontCreator.Detach();

            return true;
        }

        public bool AddPage(uint _uPageID, string _strLocation)
        {
            TextureManager.ManagedTexture tex = this.m_coreContext.GetData<TextureManager>("TextureManager").GetTexture(string.Format("{0}/{1}", this.m_strLocationPath, _strLocation));
            if ((null != tex) && (false == this.m_htblPages.ContainsKey(_uPageID)))
            {
                this.m_htblPages.Add(_uPageID, tex);
                return true;
            }
            return false;
        }

        public TextureManager.ManagedTexture GetPage(uint _uPageID)
        {
            if (false != this.m_htblPages.ContainsKey(_uPageID))
            {
                return this.m_htblPages[_uPageID] as TextureManager.ManagedTexture;
            }
            return null;
        }

        public bool AddChar(BitmapFontChar _bmfChar)
        {
            if ((null != _bmfChar) && (false == this.m_htblChars.ContainsKey(_bmfChar.ID)))
            {
                this.m_htblChars.Add(_bmfChar.ID, _bmfChar);
                return true;
            }
            return false;
        }

        public BitmapFontChar GetChar(uint _uCharID)
        {
            if (false != this.m_htblChars.ContainsKey(_uCharID))
            {
                return this.m_htblChars[_uCharID] as BitmapFontChar;
            }
            return null;
        }

        public bool AddKerning(uint _uFirst, uint _uSecond, int _sAmount)
        {
            if (false == this.m_htblKernings.ContainsKey(_uFirst))
            {
                this.m_htblKernings.Add(_uFirst, new Hashtable());
            }
            Hashtable htblFirst = this.m_htblKernings[_uFirst] as Hashtable;
            if ((0 != _sAmount) && (false == htblFirst.ContainsKey(_uSecond)))
            {
                htblFirst.Add(_uSecond, _sAmount);
                return true;
            }
            return false;
        }

        public int GetKerning(uint _uFirst, uint _uSecond)
        {
            if (false != this.m_htblKernings.ContainsKey(_uFirst))
            {
                Hashtable htblFirst = this.m_htblKernings[_uFirst] as Hashtable;
                if (false != htblFirst.ContainsKey(_uSecond))
                {
                    return (int)htblFirst[_uSecond];
                }
            }
            return 0;
        }

        public BitmapFontInfo Info
        {
            get
            {
                return this.m_bmfInfo;
            }
        }

        public BitmapFontCommon Common
        {
            get
            {
                return this.m_bmfCommon;
            }
        }
    }
}
